/*
*    Phantom v2.0 GUI Automation Software
*    Copyright (C) 2009  John C. Van Arsdall (john@phantomtest.com)
*
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License along
*    with this program; if not, write to the Free Software Foundation, Inc.,
*    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/

#include "StdAfx.h"
#include ".\datajavawindow.h"
#include "MinionLib_External.h"
#include "Java_InternalErrors.h"

CDataJavaWindow::CDataJavaWindow(void)
{
	
	if(!sType){
		sType = 1;
		sType = Factory_RegisterData((CData*)new CDataJavaWindow());
	}
	Type = sType;
	DataName = "jwindow";

	Path = 0;
	iWinTag = 0;
	
}

CDataJavaWindow::~CDataJavaWindow(void)
{
	if(Path){
		DelDataNodeTree(Path);
		Path = 0;
	}
}

CData* CDataJavaWindow::MakeData(void)
{
	return (CData*) new CDataJavaWindow();
}

SSI_BOOL CDataJavaWindow::CopyData(CData* Other)
{
	CDataJavaWindow* jother = (CDataJavaWindow*)Other;
	LocFuncSet = jother->LocFuncSet;
	return CDataWindow::CopyData(Other);
}

SSI_INT64 CDataJavaWindow::Register(SSI_INT64 NewType){
	sType = NewType;
	return 1;
}

void CDataJavaWindow::UnRegister(){
	sType = 0;
}

SSI_BOOL CDataJavaWindow::boolean()
{
  return 0;
}


SSI_BOOL CDataJavaWindow::DeleteData(CData* In)
{
	delete ((CDataJavaWindow*)In);
	return 1;
}

SSI_INT64 CDataJavaWindow::GetRegisteredType(void)
{
	return sType;
}

CStatus CDataJavaWindow::InitData(void)
{
	//MinionClear();

////

	CVariable aVar;
	aVar.Name = "Tag";
	aVar.SetType(CDataString::GetRegisteredType());
	AddVariable(aVar);

	aVar.Name = "Class";
	aVar.SetType(CDataString::GetRegisteredType());
	AddVariable(aVar);


	CFunctionDecl aNewFunc;
	//String Class;
  // JavaWin Functions
	//Class = "JavaWin";

	// There will also be 'local' functions describing the 
	// methods for each object.

	aNewFunc.Clear();
	aNewFunc.Name = "GetPath";
	aNewFunc.ReturnType = CDataString::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "ListMethods";
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.ReturnType = CDataString::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "Close";
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);
  
  aNewFunc.Clear();
	aNewFunc.Name = "LoadMethods";
	aNewFunc.ReturnType = CDataVoid::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

//  Add a singular 'LoadMethod'
//	aNewFunc.Clear();
//	aNewFunc.Name = "LoadMethod";
//	aNewFunc.ReturnType = CDataVoid::GetRegisteredType();
//	aNewFunc.SetProcessor(this);
//	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "ListFields";
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.ReturnType = CDataString::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "DispWindow";
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.ReturnType = CDataString::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "ListWindow";
//	aNewFunc.ReturnType = CDataString::GetRegisteredType();
	aNewFunc.ReturnType = CDataVoid::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "FindFrame";
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "JavaWin";
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.ReturnType = Type;
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "JavaWin";
	aNewFunc.addType(CDataInt::GetRegisteredType());
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.ReturnType = Type;
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "GetText";
	aNewFunc.ReturnType = CDataString::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "SetText";
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "SaveDecls";
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.ReturnType = CDataBool::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "Click";
	aNewFunc.ReturnType = CDataBool::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "TypeKeys";
	aNewFunc.addType(CDataString::GetRegisteredType());
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "SetFocus";
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "IsVisible";
	aNewFunc.ReturnType = CDataBool::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);

	aNewFunc.Clear();
	aNewFunc.Name = "Exists";
	aNewFunc.ReturnType = CDataBool::GetRegisteredType();
	aNewFunc.SetProcessor(this);
	CData::AddFunction(aNewFunc);
	return STAT_OK;
}

void CDataJavaWindow::SSI_FunctionProcessor(SSI_FunctionAPI& theAPI)
{
	CStatus RetStat;
	String LocClass;

	//HWND myWin;

	if(theAPI.m_FunctionName == "GetPath"){
		CDataString R;
		R.Data = GetPathString();
		theAPI.SetReturnData(&R);
		return;
	}else if(theAPI.m_FunctionName == "ListWindow"){
		ListToScreen(theAPI.m_Engine, 0);
		return;
  }

	if(theAPI.m_FunctionName == "JavaWin"){
		String sTag;
		SSI_INT64 iTag = 0;
		String sClass;

		if(theAPI.GetParameterType(0) == CDataInt::GetRegisteredType()){
			iTag = SSI_EXTRACT(CDataInt, 0);
		}else{
			sTag = SSI_EXTRACT(CDataString, 0);
		}

		sClass = SSI_EXTRACT(CDataString, 1);
		CDataJavaWindow* aWin = (CDataJavaWindow*)Factory_MakeData(CDataJavaWindow::GetRegisteredType());
		if(!aWin){
			theAPI.m_ReturnStatus = STAT_ERR; // Internal Error => Keep
		}

		aWin->WinClass = sClass;
		aWin->WinName = "JavaWin_Generic";
		aWin->WinTag = sTag;
		aWin->WinType = "jwindow";
		aWin->iWinTag = iTag;

		ConstructChildPath(aWin);
		RetStat = AddLocalVariable(aWin, aWin->WinName);
		if(!RetStat){
			delete aWin;
			theAPI.m_ReturnStatus = RetStat;
			return;
		}
		theAPI.m_ReturnStatus = theAPI.SetReturnData(aWin);
		delete aWin;
		return;
	}

	UINT Val = 0;   // Not used
	HMENU hMenu = 0;
	
	DataNode tNode = Path;
	if(tNode){
		while(tNode->Parent){
			tNode = tNode->Parent;
		}
	}

	CDataWindow* pW = new CDataWindow();
	if(tNode){
		pW->WinName = *(tNode->WinName);
		pW->WinClass = *(tNode->WinClass);
		pW->WinTag = *(tNode->WinTag);
		pW->iWinTag = tNode->iWinTag;
		pW->WinType = "jwindow";
	}else{
		pW->WinName = WinName;
		pW->WinClass = WinClass;
		pW->WinTag = WinTag;
		pW->iWinTag = iWinTag;
		pW->WinType = "jwindow";
	}

	int ctr = 0;
	while(1){
		pW->FindMe(Val, hMenu);	
		myWin = pW->myWin;
		ctr++;
		if(!myWin){
			if(ctr > 50){
				J_MAKEERR3(ERR_J00100, pW->WinName.Str(), pW->WinTag.Str(), pW->WinClass.Str())
				delete pW;
				return;
			}else{
				Sleep(100);
			}
		}else{
			break;
		}
	}

	delete pW;

  if(theAPI.m_FunctionName == "Close"){
		SendMessage(myWin, WM_CLOSE, 0, 0);
		return;
	}

	// .............................

	// OK, find another way
  //Sleep(iDelay);
	DoDelay();

	CMinionManager aMgr;
	CStatus Ret;

	DWORD tID = GetWindowThreadProcessId(myWin, SSI_NULL);
	Ret = aMgr.Initialize(tID);

	if(!Ret){
		theAPI.m_ReturnStatus = Ret;
		return;
	}

	CDataString ClassData;
	CDataString ExtraData;

	// Construct Path
	DataNode tPath = Path;
	String outTag;
	String outClass;
	while(tPath){
		outClass.Format("\"%s\"", tPath->WinClass->Str());
		if(tPath->iWinTag > 0){
			outTag.Format("%d", tPath->iWinTag);
		}else{
			outTag.Format("\"%s\"", tPath->WinTag->Str());
		}
		ExtraData.Data = ExtraData.Data + outTag + "," + outClass + ";";
		tPath = tPath->FChild;
	}
	if(iWinTag > 0){
		String Temp;
		Temp.Format("%d", iWinTag);
		ExtraData.Data = ExtraData.Data + Temp + ",\"" + WinClass + "\"";
	}else{
		ExtraData.Data = ExtraData.Data + "\"" + WinTag + "\",\"" + WinClass + "\"";
	}

	// Get directory for .class files
	char buff[4096];
	GetModuleFileName(NULL, buff, 4095);
	String str = buff;
	String dir;
	str.Reverse();
	str.Parse("\\", dir);
	str.Reverse();
	dir = str;
	dir = dir + "\\";
	ExtraData.Data = dir + ";" + ExtraData.Data;

  ClassData.Data = "";  // DEPARTURE FROM CDATAWINDOW

	// Sync local data types
	aMgr.InitLocalMap();

	if(!aMgr.WriteDataObject(&ClassData)){
		//Create Error
		return;
	}

	if(!aMgr.WriteDataObject(&ExtraData)){
		//Create Error
		return;
	}

	if(!aMgr.WriteFunctionAPI(theAPI)){
		// Create Error
		return;
	}

//  char* m = (char*) malloc(sizeof(int)*2 + sizeof(char*)); /* prepare enough memory*/
//  void* bm = m; /* copies the pointer */
//  char* string = "I am a string!!"; /* an example string */

//  (*(int*)m) = 10; /*puts the first value */
//  m += sizeof(int); /* move forward the pointer to the next element */

//  (*(char**)m) = string; /* puts the next value */
//  m += sizeof(char*); /* move forward again*/

//  (*(int*)m) = 20; /* puts the third element */
//  m += sizeof(int); /* unneeded, but here for clarity. */

//  vprintf("%d %s %d\n", (va_list)bm); /* the deep magic starts here...*/
//  free(bm);


	//char* m = new char[1024];
//	char* p = m;
//	int i = 10;
//	int j = 20;
	//memcpy(m, (const void*)&i, sizeof(i));
//	(*(int*)m) = 10;
//	m = m + sizeof(i);
//	(*(int*)m) = 20;
  //memcpy(m, (const void*)&j, sizeof(j));
//	printf("DATA: %d, %d\n", p);
	//delete p;
//	free(p);

//	printf("TESTING -----\n");

	if(1){
		Ret = aMgr.DoFunction((LPARAM)myWin);
		if(!Ret){
			theAPI.m_ReturnStatus = Ret;
			return;
		}
		aMgr.ResetMap();

	// This is the test section
	}else{
		Ret = aMgr.DoFunction((LPARAM)myWin);
		//GetGlobalManager()->GetMap();
		aMgr.ResetMap();
		//printf("DLL MAP Address: %d\n", GetGlobalManager()->MapPtr_0);

		//printf("hi");

		// THIS IS A CUSTOM FUNCTION ---------------------------------------
		SSI_FunctionAPI theAPI;
		String ClassData;
		String ExtraData;
		if(!ReadAPI(theAPI, ClassData, ExtraData, &aMgr)){
		//if(!ReadAPI(theAPI, ClassData, ExtraData, GetGlobalManager())){

			//SetMinionSync(1);
			// Set a returned error
	  	return;
		}

		//MinionLog("API Recieved");
	}


	Ret = aMgr.ReadResponse(theAPI);
	if(!Ret){
		theAPI.m_ReturnStatus = Ret;
		return;
	}

	if(theAPI.m_FunctionName == "LoadMethods"){
		// The return will be used to load the functions

		// Must override the return type
		// Type is already OK... doing this will wipe out the data array
		//theAPI.GetReturnData()->SetType(CDataString::GetRegisteredType());
		CVariable* RetVar = theAPI.GetReturnData();
		if(!RetVar){
			theAPI.m_ReturnStatus = STAT_ERR;
		}
		CDataString S = (CDataString&)RetVar->GetWorkingData();
		String sMethods = S.Data;

		// Parse string and add to *local* function set
		LoadFunctions(S.Data);

		CDataVoid aVoid;
		theAPI.GetReturnData()->SetType(CDataVoid::GetRegisteredType());
		theAPI.SetReturnData(&aVoid);
	}

	Ret = aMgr.Cleanup();
	if(!Ret){
		theAPI.m_ReturnStatus = Ret;
		return;
	}


	// Regular (MINION) mode
	if(1){
		// Get the process ID
		//DWORD tID = GetWindowThreadProcessId(myWin, SSI_NULL);
		// Set the Minion Hook
		//HWND hMinion = SetMinionHook(tID, 1);

		// Get the memor map pointer
		//aptr = (char*)aMap.MakePointer();

		// If Minion never hooked, return error
		//if(!hMinion){
		//	P_MAKEERR0(ERR_P00300);
			// "Phantom Internal Error: Minion not created"
		//	return;
		//}



		//ClassData.Data = "jvm";  // DEPARTURE FROM CDATAWINDOW
		//SSI_INT64 BytesWrote = WriteDataObject(aptr, &ClassData);
		//BytesWrote = BytesWrote + WriteDataObject(aptr+BytesWrote, &ExtraData);
		//WriteFunctionAPI(aptr+BytesWrote, theAPI);

		//ClearMinionSync();
		//MinionLog("--- Sending Tags...");

		// Sync the data types
		//PostThreadMessage(tID, WM_COMMAND, MINION_SETINTTYPE, (LPARAM)CDataInt::GetRegisteredType());
		//PostThreadMessage(tID, WM_COMMAND, MINION_SETSTRINGTYPE, (LPARAM)CDataString::GetRegisteredType());
		//PostThreadMessage(tID, WM_COMMAND, MINION_SETBOOLTYPE, (LPARAM)CDataBool::GetRegisteredType());
		//PostThreadMessage(tID, WM_COMMAND, MINION_SETREALTYPE, (LPARAM)CDataReal::GetRegisteredType());
		//PostThreadMessage(tID, WM_COMMAND, MINION_SETVOIDTYPE, (LPARAM)CDataVoid::GetRegisteredType());  /// MUST BE LAST
		//PostThreadMessage(tID, WM_COMMAND, MINION_DOFUNCTION, (LPARAM)myWin);

		// Create a new API to read from the pointer
		//MINION_FunctionAPI newAPI;

		//if(!WaitForSync(1000)){
		//	P_MAKEERR0(ERR_P00301);  // Internal Error
		//	MinionLog("No Sync Flag");
		//}else{
		//	MinionLog("Attempting Read");
			// Read the new API
		//	ReadFunctionAPI(aptr, newAPI);

			// Set the return status and returned data
		//	theAPI.m_ReturnStatus = newAPI.m_ReturnStatus;
		//	theAPI.SetReturnData(newAPI.GetReturnData());
		//}

		//ClearMinionSync(); 
		// Unmap the pointer
		//aMap.UnMap(aptr);

		// Remove the hook
		//SetMinionHook(tID, 0);

		// TEMPORARY
		//if(theAPI.m_ReturnStatus){
		//	if(theAPI.m_FunctionName == "TypeKeys"){
		//		String sKeys = SSI_EXTRACT(CDataString, 0);
		//		CDataWindow W;
		//		theAPI.m_ReturnStatus = W.TypeKeys(NULL, sKeys);
		//	}
		//}


	}
}

void CDataJavaWindow::LoadFunctions(String& Funcs){
	LocFuncSet.Funcs.Clear();
	CFunctionDecl aFunc;

	String P;
	String S;
	String Junk;
	String Params;
	String Name;
	String Return;

	StringTree List;
	Funcs.Parse(String("\n"), List, 1);
	StringNode* top = List.getTop();
	while(top){
		top->Get(S);
		S.Reverse();
		S.Parse(")", Junk);
		S.Parse("(", Params);
		S.Parse(". ", Name, &Junk);
		if(Junk == "."){   // If it is a method, the return type will be the class if this is not done
			S.Parse(" ", Junk);
		}
		S.Parse(" ", Return);
		Params.Reverse();
		Name.Reverse();
		Return.Reverse();

		aFunc.Clear();
		StringTree ParamTree;
		if(Params.Parse(String(","), ParamTree, 1)){
			StringNode* pTop = ParamTree.getTop();
			while(pTop){
				pTop->Get(P);
				SSI_INT64 I = PrimitiveFromType(P);
				if(I != CDataVoid::GetRegisteredType()){
					aFunc.addType(I);
				}
				pTop = pTop->next();
			}
		}

		aFunc.ReturnType = PrimitiveFromType(Return);
		aFunc.Name = Name;
		aFunc.SetProcessor(this);		
		LocFuncSet.AddFunction(aFunc);
		top = top->Next;
	}

		// NO!  Dont do parsing here, since it will have to be
		// parsed again anyway later...

		// Maybe not... is there a better way?  I think so...
		//Parse space to get return
		//Parse ( to get name
		  // Find last '.' and parse away
		//Parse ) to get params
		  // For each param, either replace
		  // with known type, or replace with jobject
//		top = top->next();
//	}
//	return Ret;


//		aFunc.Clear();
//		aFunc.Name = "TESTING";
//		aFunc.ReturnType = CDataString::GetRegisteredType();
//		aFunc.SetProcessor(this);
//		aFunc.addType(CDataString::GetRegisteredType());
//		LocFuncSet.AddFunction(aFunc);
}

void CDataJavaWindow::DisplayMembers(ssi_stream* out)
{
	if(!out) return;
	String s;
	SSI_CHAR StrBuff[68];

	// --- MEMBER VARIABLES ---
//	if(VarSet){
//		CVariable Var;
//		VarItor Itor = VarSet->begin();
//		s = "<Member Variables>";
//
//		CSSI_CHAR* fmt = "%-25.24s%-42.42s";
//
//		sprintf(StrBuff, fmt, "Name", "Type");
//		out->Disp(s.Str(), 1);
//		out->Disp(StrBuff, 1);
//		out->Disp("------------------------------------------------------------------------------", 1);
//
//		while(Itor != VarSet->end()){
//			Var = *Itor;
//			sprintf(StrBuff, fmt, Var.Name.Str(), Var.GetTypeString().Str());
//			out->Disp(StrBuff, 1);
			//aNode = aNode->next();
//			++Itor;
//		}
//	}

	// --- LOADED FUNCTIONS ---
	CFunctionDecl aDecl;
	SSI_INT64 NumParams = 0;
	SSI_INT64 ctr = 0;
	SSI_INT64 Type = 0;
	String sParams;
	String sReturn;

	FuncNode* aNode = LocFuncSet.Funcs.getTop();
	CSSI_CHAR* fmt = "%-25.24s%-12.11s%-30.30s";
	s = "<Loaded Functions>";
	sprintf(StrBuff, fmt, "Name", "Return", "Parameters");
	out->Disp(s.Str(), 1);
	out->Disp(StrBuff, 1);
	out->Disp("------------------------------------------------------------------------------", 1);
	while(aNode){
		sParams = "";
		aNode->Get(aDecl);
		NumParams = aDecl.getNumParams();
		for(ctr = 0; ctr < NumParams; ctr++){
			Type = aDecl.getParamType(ctr);
			CData* aData = Factory_MakeData(Type);
			if(aData){
				sParams = sParams + aData->DataName + ",";
				delete aData;
			}
		}
		sParams.chop();

		CData* aData = Factory_MakeData(aDecl.ReturnType);
		if(aData){
			sReturn = aData->DataName;
			delete aData;
		}
		sprintf(StrBuff, fmt, (CSSI_CHAR*)aDecl.Name, (CSSI_CHAR*)sReturn, (CSSI_CHAR*)sParams);
		out->Disp(StrBuff, 1);
		aNode = aNode->next();
	}
	out->Disp("", 1);
	CData::DisplayMembers(out);
}


SSI_INT64 CDataJavaWindow::PrimitiveFromType(String& Class){
	Class.Trim();
	if(Class == "boolean"){
		return CDataBool::GetRegisteredType();
	}
	if(Class == "int"){
		return CDataInt::GetRegisteredType();
	}
	if(Class == "void" || Class == ""){
		return CDataVoid::GetRegisteredType();
	}
	if(Class == "java.lang.String"){
		return CDataString::GetRegisteredType();
	}
	if(Class == "float"){
		return CDataReal::GetRegisteredType();
	}
	return GetRegisteredType();

}

CStatus CDataJavaWindow::EvalFunction(VarItor TopVar, VarTree& InTree, CStatement& aStat)
{
	// If TopVar... Find Var from registered list, send to EvalFunction
	CStatus RetStat;
  CFunctionDecl aDecl;
	SSI_FunctionAPI theAPI;

	theAPI.m_Engine = aStat.Engine;

	RetStat = LocFuncSet.CheckFunction(aStat.aFunction, theAPI, aDecl);
	if(RetStat){
		//if(aDecl.FunctionType == CDATA_FUNCTION_TYPE){
			this->SSI_FunctionProcessor(theAPI);
		//}else{
		//	return STAT_ERR;  // This is an internal error
		//}
	  
		if(!theAPI.m_ReturnStatus){
			return theAPI.m_ReturnStatus;
		}
	  
		CVariable* pVar = theAPI.GetReturnData();
		//if(!pVar){
		//	if(!theAPI.m_ReturnStatus){
		//		return theAPI.m_ReturnStatus;
		//	}
		//	MAKEERR2(ERR03335, aDecl.Name.Str(), CInterpreter::GetVariableString(aDecl.ReturnType).Str());
		//}

		//if(theAPI.GetReturnData()->GetType() != aDecl.ReturnType){
		//	MAKEERR2(ERR03336, aDecl.Name.Str(), CInterpreter::GetVariableString(aDecl.ReturnType).Str());
		//}

		aStat.aFunction.SetReturn(*pVar);
		return theAPI.m_ReturnStatus;
	}else{
		return CData::EvalFunction(TopVar, InTree, aStat);
	}
}

SSI_BOOL CDataJavaWindow::IsFunction(const String& fName)
{
	CFunctionDecl aDecl;
  aDecl.Name = fName;
  aDecl.Name.Trim();
	if(LocFuncSet.IsFunction(aDecl)){
		return 1;
	}
	return CData::IsFunction(fName);
}
